﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace UCControlBase
{
    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(System.ComponentModel.Design.IDesigner))]
    public partial class ControlBase : UserControl
    {
        /// <summary>
        /// 是否圆角
        /// </summary>
        private bool _isRadius = true;
        [Description("是否圆角"), Category("自定义")]
        public virtual bool IsRadius
        {
            get { return _isRadius; }
            set { _isRadius = value; }
        }

        /// <summary>
        /// 圆角角度
        /// </summary>
        private int _cornerRadius = 24;
        [Description("圆角角度"), Category("自定义")]
        public virtual int CornerRadius
        {
            get { return _cornerRadius; }
            set
            {
                if (value < 1)
                    _cornerRadius = 1;
                else
                    _cornerRadius = value;
            }
        }

        /// <summary>
        /// 是否显示边框
        /// </summary>
        private bool _isShowRect = true;
        [Description("是否显示边框"), Category("自定义")]
        public virtual bool IsShowRect
        {
            get { return _isShowRect; }
            set { _isShowRect = value; }
        }

        /// <summary>
        /// 边框颜色
        /// </summary>
        private Color _rectColor = Color.Red;
        [Description("边框颜色"), Category("自定义")]
        public virtual Color RectColor
        {
            get { return _rectColor; }
            set
            {
                _rectColor = value;
                Refresh();
            }
        }

        /// <summary>
        /// 边框宽度
        /// </summary>
        private int _rectWidth = 1;
        [Description("边框宽度"), Category("自定义")]
        public virtual int RectWidth
        {
            get { return _rectWidth; }
            set { _rectWidth = value; }
        }

        /// <summary>
        /// 填充颜色
        /// </summary>
        private Color _fillColor = Color.Transparent;
        [Description("当使用边框时填充颜色，当值为背景色或透明色或空值则不填充"), Category("自定义")]
        public virtual Color FillColor
        {
            get { return _fillColor; }
            set { _fillColor = value; }
        }

        public ControlBase()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.Selectable, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.UserPaint, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (this.Visible)
            {
                if (_isRadius)
                    SetWindowRegion();
                else//不显示圆角，则显示原矩形
                {
                    GraphicsPath g = new GraphicsPath();
                    g.AddRectangle(base.ClientRectangle);
                    g.CloseFigure();
                    base.Region = new Region(g);
                }

                GraphicsPath graphicsPath = new GraphicsPath();
                if (this._isShowRect || (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != this.BackColor))
                {
                    Rectangle clientRectangle = base.ClientRectangle;
                    if (_isRadius)
                    {
                        graphicsPath.AddArc(0, 0, _cornerRadius, _cornerRadius, 180f, 90f);
                        graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, 0, _cornerRadius, _cornerRadius, 270f, 90f);
                        graphicsPath.AddArc(clientRectangle.Width - _cornerRadius - 1, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 0f, 90f);
                        graphicsPath.AddArc(0, clientRectangle.Height - _cornerRadius - 1, _cornerRadius, _cornerRadius, 90f, 90f);
                        graphicsPath.CloseFigure();
                    }
                    else
                    {
                        Rectangle r = new Rectangle(clientRectangle.X, clientRectangle.Y, clientRectangle.Width - 1, clientRectangle.Height - 1);
                        graphicsPath.AddRectangle(r);
                        graphicsPath.CloseFigure();
                    }
                }
                e.Graphics.SetGDIHigh();
                if (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != this.BackColor)
                    e.Graphics.FillPath(new SolidBrush(this._fillColor), graphicsPath);
                if (this._isShowRect)
                {
                    Color rectColor = this._rectColor;
                    Pen pen = new Pen(rectColor, (float)this._rectWidth);
                    e.Graphics.DrawPath(pen, graphicsPath);
                }
            }
            base.OnPaint(e);
        }

        private void SetWindowRegion()
        {
            GraphicsPath path = new GraphicsPath();
            Rectangle rect = new Rectangle(-1, -1, base.Width + 1, base.Height);
            path = GetRoundedRectPath(rect, _cornerRadius);
            base.Region = new Region(path);
        }

        private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
        {
            Rectangle rect2 = new Rectangle(rect.Location, new Size(radius, radius));
            GraphicsPath graphicsPath = new GraphicsPath();
            graphicsPath.AddArc(rect2, 180f, 90f);//左上角
            rect2.X = rect.Right - radius;
            graphicsPath.AddArc(rect2, 270f, 90f);//右上角
            rect2.Y = rect.Bottom - radius;
            rect2.Width += 1;
            rect2.Height += 1;
            graphicsPath.AddArc(rect2, 360f, 90f);//右下角
            rect2.X = rect.Left;
            graphicsPath.AddArc(rect2, 90f, 90f);//左下角
            graphicsPath.CloseFigure();
            return graphicsPath;
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg != 20)
                base.WndProc(ref m);
        }
    }

    public static class ControlHelper
    {
        public static void SetGDIHigh(this Graphics g)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高，即消除锯齿
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;
        }
    }
}
